import { Singleton } from '../../framework/common/Singleton';
import { RemoteMgr } from './remoteMgr';
import { RemoteData, RemoteType } from '../../../../shares/sharesApp';
import type {
    DialogEndData,
    DialogData,
    DialogKeyData,
} from '../../../../shares/sharesApp';
import i18n from '../../../../i18n';

interface IdialogData {
    title: string;
    content: string;
}

export class DialogMgr extends Singleton<DialogMgr>() {
    size: number = 0;
    data: IdialogData = { title: '', content: '' };
    resolve: () => void = () => null;
    backGround: UiBox = UiBox.create();
    box: UiBox = UiBox.create();
    title: UiText = UiText.create();
    content: UiText = UiText.create();
    titleBackgroundImage: UiImage = UiImage.create();
    contentBackgroundImage: UiImage = UiImage.create();
    tip: UiText = UiText.create();

    constructor() {
        super();
    }

    start(): void {
        this.init();
        this.bindEvents();
    }
    bindEvents() {
        RemoteMgr.instance.onClientEvent(async (event) => {
            let content: string[] = [];
            if (event.type === 'dialog') {
                const data = event.data as DialogData;
                content =
                    data.title === ''
                        ? data.content
                        : data.content.map((item) => `${data.title}: ${item}`);
            } else if (event.type === 'dialogKey') {
                const data = event.data as DialogKeyData;
                switch (data.key) {
                    case 'game.start':
                        content = [i18n.t('game.start')];
                        break;
                    case 'game.choose_poison_timeout':
                        content = [i18n.t('game.choose_poison_timeout')];
                        break;
                    case 'game.choose_candy':
                        content = [
                            i18n.t('game.choose_candy', data.params as any),
                        ];
                        break;
                    case 'game.end_1.result':
                        content = [
                            i18n.t('game.end_1.result', data.params as any),
                        ];
                        break;
                    case 'game.end_2.result':
                        content = [
                            i18n.t('game.end_2.result.1'),
                            i18n.t('game.end_2.result.2'),
                            i18n.t('game.end_2.result.3'),
                            i18n.t('game.end_2.result.4', data.params as any),
                        ];
                        break;
                    case 'first_login':
                        content = [
                            i18n.t('first_login.1'),
                            i18n.t('first_login.2'),
                            i18n.t('first_login.3'),
                            i18n.t('first_login.4'),
                            i18n.t('first_login.5'),
                            i18n.t('first_login.6'),
                            i18n.t('first_login.7'),
                            i18n.t('first_login.8'),
                            i18n.t('first_login.9'),
                            i18n.t('first_login.10'),
                            i18n.t('first_login.11'),
                        ];
                        break;
                    default:
                        throw new Error(
                            `(Client) Invalid i18n key:${data.key}`
                        );
                }
            } else if (event.type === 'dialogClose') {
                this.backGround.visible = false;
                return;
            }
            (async () => {
                for (let i = 0; i < content.length; i++) {
                    await this.show({
                        title: '',
                        content: `${content[i]}`,
                    });
                }
            })().then(() => {
                RemoteMgr.instance.send<DialogEndData>({
                    type: RemoteType.DIALOG_END,
                    data: null,
                });
            });
        });
    }

    init(): void {
        this.size = screenWidth;

        this.backGround.parent = ui;
        this.backGround.size.offset.copy(Vec2.create({ x: 0, y: 0 }));
        this.backGround.size.scale.copy(Vec2.create({ x: 1, y: 1 }));
        this.backGround.backgroundColor.copy(Vec3.create({ r: 0, g: 0, b: 0 }));
        this.backGround.backgroundOpacity = 1;
        this.backGround.visible = false;

        this.backGround.events.on('pointerdown', () => {
            if (this.data.content !== this.content.textContent) {
                this.content.textContent = this.data.content;
            } else {
                this.backGround.visible = false;
                this.resolve();
            }
        });

        this.box.parent = this.backGround;
        this.box.position.scale.copy(Vec2.create({ x: 0.1, y: 0.1 }));
        this.box.size.offset.copy(Vec2.create({ x: 0, y: 0 }));
        this.box.size.scale.copy(Vec2.create({ x: 0.8, y: 0.8 }));
        this.box.backgroundColor.copy(Vec3.create({ r: 0, g: 0, b: 0 }));
        this.box.backgroundOpacity = 0;
        this.box.visible = true;

        this.content.parent = this.box;
        this.content.position.offset.copy(Vec2.create({ x: 0, y: 0 }));
        this.content.size.offset.copy(Vec2.create({ x: 0, y: 0 }));
        this.content.size.scale.copy(Vec2.create({ x: 1, y: 1 }));
        this.content.textColor.copy(Vec3.create({ r: 255, g: 255, b: 255 }));
        this.content.backgroundOpacity = 0;
        this.content.textFontSize = this.size / 50;
        this.content.autoWordWrap = true;
        this.content.textXAlignment = 'Center';
        this.content.textYAlignment = 'Center';

        this.tip.parent = this.backGround;
        this.tip.position.offset.copy(
            Vec2.create({ x: -this.size / 10, y: -this.size / 40 })
        );
        this.tip.position.scale.copy(Vec2.create({ x: 1, y: 1 }));
        this.tip.size.offset.copy(
            Vec2.create({ x: this.size / 10, y: this.size / 40 })
        );
        this.tip.backgroundOpacity = 0;
        this.tip.textColor.copy(Vec3.create({ r: 255, g: 255, b: 255 }));
        this.tip.textFontSize = this.size / 75;
        this.tip.textXAlignment = 'Center';
        this.tip.textYAlignment = 'Center';
        this.tip.textContent = '点击屏幕继续';
    }

    show(data: IdialogData): Promise<void> {
        input.unlockPointer();
        this.backGround.visible = true;
        this.data = data;
        const { title, content } = data;
        this.title.textContent = title;
        this.content.textContent = '';
        return new Promise<void>(async (resolve) => {
            this.resolve = resolve;
            for (let i = 0; i < this.data.content.length; i++) {
                if (this.data.content === this.content.textContent) {
                    break;
                }
                this.content.textContent += content[i];
                await sleep(46);
            }
        });
    }
}
